<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2022/7/22 0022
 * Time: 19:36
 */

namespace framework\library;


class Route
{
    protected static $instance;

    protected $httpMethods = ["GET", "POST", "PUT", "DELETE"];

    // 静态路由
    protected $staticRoute = [];

    // 动态路由
    protected $dynamicRoute = [];

    public static function getInstance()
    {
        if (is_null(self::$instance)) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    // 注册路由
    public function register($name, $arguments)
    {
        $upperName = strtoupper($name);
        if (in_array($upperName, $this->httpMethods)) {
            list($route, $handler) = $arguments;

            $parseRes = $this->parse($route);

            if (is_array($parseRes) && count($parseRes[1]) > 0) {
                $this->addDynamicRoute($upperName, $route, $handler, $parseRes);
            } else {
                $this->addStaticRoute($upperName, $route, $handler);
            }
        }
    }

    // 静态路由注册
    protected function addStaticRoute($method, $route, $handler)
    {
        $this->staticRoute[$method][$route] = $handler;
    }

    // 动态路由注册
    protected function addDynamicRoute($method, $route, $handler, $variable)
    {
        $this->dynamicRoute[$method][$route] = [
            "handle" => $handler,
            "var" => $variable
        ];
    }

    // 提取路由中的占位符
    protected function parse($route)
    {
        $regex = '~^(?:/[a-zA-Z0-9_]*|/\{([a-zA-Z0-9_]+?)\})+/?$~';
        // $matches: [[0]=> string(18) "/article/list/{id}" [1]=> string(2) "id"]
        if (preg_match($regex, $route, $matches)) {
            // 动态
            if (count($matches) > 1) {
                preg_match_all('~\{([a-zA-Z0-9_]+?)\}~', $route, $matchesVariables);

                return [
                    preg_replace('~{[a-zA-Z0-9_]+?}~', '([a-zA-Z0-9_]+)', $route),
                    $matchesVariables[1][0]
                ];

            } else {
                return [$route, []];
            }
        }
    }

    public function getStaticRoute()
    {
        return $this->staticRoute;
    }

    public function getDynamicRoute()
    {
        return $this->dynamicRoute;
    }

    public function __call($name, $arguments)
    {
        return static::getInstance()->register($name, $arguments);
    }

    public static function __callStatic($name, $arguments)
    {
        return static::getInstance()->register($name, $arguments);
    }

}